#include <iostream>
#include <sstream>
#include <unistd.h>

//gl
#include <glad/glad.h>
#include "gl/GLRenderer.h"

// vk
#include "vk/VkRenderer.h"

#include "GLFW/glfw3.h"

uint32_t width = 800;
uint32_t height = 800;
bool isPlaying = true;

int main(int argc, char* argv[]){
    std::cout<<"YUV(NV12) & RGB!"<<std::endl;

    std::string graphicArgValue;
    std::string yuvFile;
    std::string rgbFile;
    for (int i = 1; i < argc; i++) {
        if (std::string(argv[i]) == "-g") {
            if (i + 1 < argc) {
                graphicArgValue = argv[i + 1];
            }
        }
        if (std::string(argv[i]) == "-yuv") {
            if (i + 1 < argc) {
                yuvFile = argv[i + 1];
            }
        }
        if (std::string(argv[i]) == "-rgb") {
            if (i + 1 < argc) {
                rgbFile = argv[i + 1];
            }
        }
    }
    if(graphicArgValue.empty()){
        std::cerr << "-g argument can not be empty." << std::endl;
        return -1;
    }
    if(yuvFile.empty() && rgbFile.empty()){
        std::cerr << "-yuv and -rgb arguments can not be both empty." << std::endl;
        return -1;
    }
    bool isOpenGL = graphicArgValue == "OpenGL";
    bool isYuvFile = !yuvFile.empty();

    if(!glfwInit()){
        std::cerr << "Failed init glfw!" << std::endl;
        return -1;
    }

    if(isOpenGL){
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
    } else {
        glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    }
    GLFWwindow* pWindow = glfwCreateWindow(width, height, "YUV(NV12) & RGB", nullptr, nullptr);
    if(!pWindow){
        std::cerr << "Failed create glfw window!" << std::endl;
        return -1;
    }
    glfwMakeContextCurrent(pWindow);
    glfwSetFramebufferSizeCallback(pWindow, [](GLFWwindow* window, int w, int h){
        width = w;
        height = h;
    });

    if(isOpenGL){
        GLRenderer::gl_init(isYuvFile, yuvFile, rgbFile);
    } else {
        VkRenderer::vk_init(pWindow, isYuvFile, yuvFile, rgbFile);
    }

    // 4.主循环
    uint32_t currentFrame = 0;
    while (!glfwWindowShouldClose(pWindow)) {
        glfwPollEvents();

        if(isOpenGL){
            GLRenderer::gl_render(width, height, isPlaying);
        } else {
            VkRenderer::vk_render(currentFrame, width, height, isPlaying);
        }

        glfwSwapBuffers(pWindow);
        currentFrame = (currentFrame + 1) % 2;

        usleep(15.9f * 1000);
    }

    if(isOpenGL){
        GLRenderer::gl_destroy();
    } else {
        VkRenderer::vk_destroy();
    }

    glfwDestroyWindow(pWindow);
    glfwTerminate();

    return 0;
}